package cn.dai.Reflection;

import org.junit.Test;

import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.Properties;
import java.util.Random;

/**
 * @author ArkD42
 * @file 1 - Java基础语法
 * @create 2020 - 04 - 22 - 22:57
 */
public class Loader {

    @Test
    public void loader() throws Exception {
        Properties properties = new Properties();
        // 流对象读取只能读取在当前源码工程的目录下
        FileInputStream inputStream = new FileInputStream("jdbc.properties");
        properties.load(inputStream);
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");
        System.out.println(driver);
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);
        inputStream.close();
    }

    @Test
    public void loader2() throws Exception {
        // 创建配置实例
        Properties properties = new Properties();
        // 类加载器读取 文件的位置默认是在当前Module或者项目的src包下
        InputStream inputStream = Loader.class.getClassLoader().getResourceAsStream("jdbc.properties");
        // 加载
        properties.load(inputStream);

        // 读取信息
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");

        System.out.println(driver);
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);

        inputStream.close();
    }

    @Test
    public void loader3() throws Exception {
        // 创建配置实例
        Properties properties = new Properties();
        // 返回URL的编码 %20  类加载器读取 文件的位置默认是在当前Module或者项目的src包下
        String path = Loader.class.getClassLoader().getResource("jdbc.properties").getFile();
        // 需要解码
        String decode = URLDecoder.decode(path, "UTF-8");
        // 创建流对象
        InputStream inputStream = new FileInputStream(decode);
        // 加载配置
        properties.load(inputStream);

        // 读取信息
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");

        System.out.println(driver);
        System.out.println(url);
        System.out.println(username);
        System.out.println(password);

        inputStream.close();
    }

    @Test
    public void getInstanceByReflect() throws Exception {
        Class<Person> personClass = Person.class;

        // 直接用类的类实例创建对象 在JDK9+ 以后不推荐使用此方法创建实例了
        // .newInstance(); 内部调用运行时的空参构造器，没有空参构造，调用异常
        // 运行时类必须提供空参构造器，访问权限不得低于默认

        // javaBean 要求提供一个空参构造器的原因：
        // 通过这个反射调用构造器创建Bean的实例
        // 子类继承运行时类时，调用super()保证父类也有此构造器

        Person person = personClass.newInstance();
        System.out.println(person);
    }

    /**
     * 表现反射动态性的演示
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    @Test
    public void dynamic() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        for (int i = 0; i < 100; i++) {
            int random = new Random().nextInt(3);
            String classPath = null;
            switch (random){
                case 0:
                    classPath = "java.util.Date";
                    break;
                case 1:
                    classPath = "java.lang.Object";
                    break;
                case 2:
                    classPath = "cn.dai.Reflection.Person";
            }

            Class<?> name = Class.forName(classPath);
            Object instance = name.newInstance();
            System.out.println(instance);
        }
    }
}
